// 这个文件是服务端
// 服务端负责 :
// 1 . 创建共享内存
// 2 . 接收共享内存传来的客户端发来的消息
// 3 . 结束后 , 销毁共享内存 , 必须用代码或指令删除 , 因为共享内存生命周期随内核 !

#include "shm.hpp"
#include "FIFO.hpp"

int main()
{
    Shm_m shm(CREATER); // 构造时会自动创建共享内存

    ////////// ***********   创建管道
    // 构造时就会创建管道文件
    NameFifo fifo(PATH, FILENAME);

    // 文件操作
    FileOper file(PATH, FILENAME);
    file.OpenForRead();

    ////////// ***********   创建管道

    // 2.  挂接 , 映射到进程地址空间
    shm.Attach();

    // 挂接完成后 , 即 : 映射到两个进程虚拟地址空间中了 , 至此二者看到了同一份资源
    // 然后就可以通信了 !
    // 所以 , 服务端就可以使用共享内存来通信了 , 怎么使用 ?? 得到的就是一块内存 , 有地址直接用即可 !

    // 3. 获取映射后的虚拟起始地址
    char *addar = (char *)shm.VirtualAddar();
    // 4. 进行通信 , 读取共享内存中的内容
    int cnt = 0;
    while (true)
    {
        // 1 . 先从管道读 , 读到内容了证明需要去共享内存读了
        if (file.WaitWakup())
        {
            // 直接读
            printf("I am %s , %s say : %s\n", CREATER, USER, addar);
            std::string st = addar;
            // std::cout << st << std::endl;

            if (st.rfind('Z') == 25)
            {
                std::cout << USER << " exit , me too !" << std::endl;
                break;
            }
        }
        else
            break;
    }

    // 服务端还要负责销毁共享内存 , 因为共享内存生命周期随内核 , 不用了需要销毁 !

    file.Close();
    std::cout << "server end normal!" << std::endl;

    // 5 . 销毁
    // 这里进程结束 , 会走析构函数 , 析构时会自动进行销毁

    return 0;
}